package com.example.demo.netty.heart;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MyWebSocketServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel sc) throws Exception {
                            ChannelPipeline pipeline = sc.pipeline();
                            pipeline.addLast(new HttpServerCodec())
                                    .addLast(new ChunkedWriteHandler())
                                    .addLast(new ReadTimeoutHandler(50))
                                    .addLast(new HttpObjectAggregator(4))
                                    .addLast(new IdleStateHandler(0, 0, 10))
                                    .addLast(new WebSocketServerProtocolHandler("/ws"))
                                    .addLast(new MyWebSocketHandler())
                            ;
                        }
                    });
            ChannelFuture cf = serverBootstrap.bind(8888).sync();
            System.out.println("启动正在监听： " + cf.channel().localAddress());
            Thread scanner = createScanner();
            scanner.setName("thread-sendmessage");
            scanner.start();
            cf.channel().closeFuture().sync();
        } catch (Exception e) {
            bossGroup.shutdownGracefully().sync();
            workerGroup.shutdownGracefully().sync();
        }


    }

    private static Thread createScanner() {
        return new Thread(() -> {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                try {
                    String s = br.readLine();
                    TextWebSocketFrame text = new TextWebSocketFrame(s);
                    MyWebSocketHandler.channels.forEach(ch -> {
                        System.out.println("server send " + ch.remoteAddress() + " " + text);
                        ch.writeAndFlush(text);
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    // .addLast(new LoginAuthRespHandler())
    //  .addLast(new HeartBeatRespHandler());
}
